<?php

declare(strict_types=1);
// 用户后台导航菜单
namespace app\net2023dev\controller;

use think\facade\Db; //门面模式
use app\net2023dev\model\Menu as mysql; //导入模型

class Menu
{

    public function index()
    {
        // return app('http')->getName(); //多应用模式下如 何获取当前应用名
        return '您好！这是一个[demo]示例应用' . time();
        // return $this->hello() . ' - Version：' . \think\facade\App::version();
    }
    public function hello($name = 'ThinkPHP8')
    {
        return $name;
    }
    public function Son()
    {
        // 读数据库
        $sqldb = mysql::where([['id', '>', -1]])->order("i", "desc")->select()->toArray(); //以数组方式返回


        // 1.生成树数据
        // 2.找父ID（分解成一维数组-倒序）
        $clsTree =  $this->get_Tree($sqldb, 0); //生成树数据
        // $s = array_values($cateTree); //关联数组转索引数组
        $apidb = [
            'msg' => '分类',
            'code' => 2005, //状态码
            'clsTree' => $clsTree,
        ];
        return json($apidb);
    }


    //多维转为一维数组 
    function get_all_array_walk($array, $overturn = true)
    {
        $arr = [];
        array_walk_recursive($array, function ($value) use (&$arr) {
            array_push($arr, $value);
        });
        // 是否翻转
        if ($overturn) {
            $arr = array_reverse($arr, false); //翻转顺序的数组
        }
        // return json_encode($arr);
        return $arr;
    }
    // 递归获取所有的子分类----生成无限级分类树数据
    function get_Tree($db, $pid, $level = 0)
    {
        // dump($db);
        // exit;
        $time_int = time();
        $time = date('Y-m-d H:i:s', $time_int);
        $default = json_encode([[], $time]);
        $tree = []; //每次都声明一个新数组用来放子元素
        foreach ($db as $v) {
            if ($v['pid'] == $pid) { //匹配子记录
                // unset($v['ids']);
                $v['level'] = $level; //当前层级

                $pids =  $this->get_pids($db, $v['id']); // 用自己的ID找所有祖先ID
                $v['pids'] = $this->get_all_array_walk($pids); //多维转为一维数组
                $v['pids_count'] = count($v['pids']);
                $ids = $this->get_ids($db, $v['id']); //用自己的ID找所有子孙ID
                $v['ids'] = $this->get_all_array_walk($ids, false); //多维转为一维数组
                array_unshift($v['ids'], $v['id']); //自己ID插入到数组的开头
                $v['ids_count'] = count($v['ids']);

                $v['title'] =  $v['name'];

                //更新数据库
                $sqldb = mysql::where([['id', '=',  $v['id']]])->find();
                $sqldb->pids = isset($v['pids']) ? json_encode([$v['pids'], $time])  : $default;
                $sqldb->ids = isset($v['ids']) ? json_encode([$v['ids'], $time])  : $default;
                $sqldb->end_node = 0; //末端节点_0否1是
                $sqldb->save();

                $v['children'] = $this->get_Tree($db, $v['id'], $level + 1); //递归获取子记录
                if ($v['children'] == null) {
                    $v['children'] = [];
                    $sqldb = mysql::where([['id', '=',  $v['id']]])->find();
                    $sqldb->end_node = 1; //末端节点_0否1是
                    $sqldb->save();
                    unset($v['children']); //如果子元素为空则unset()进行删除，说明已经到该分支的最后一个元素了（可选）
                }

                if ($v['type'] == null || $v['type'] == "") {
                    unset($v['type']);
                }
                unset($v['Idx']);
                unset($v['pid']);
                unset($v['i']);
                unset($v['ids']);
                unset($v['pids']);
                unset($v['end_node']);
                unset($v['spread']);
                unset($v['level']);
                unset($v['pids_count']);
                unset($v['ids_count']);
                unset($v['name']);
                $tree[] = $v; //将记录存入新数组
            }
        }
        return $tree; //返回新数组
    }
    // 通过子类获取所有的父类
    function get_pids($db, $id)
    {
        $data = [];
        foreach ($db as $item) {
            if ($item['id'] == $id) {
                $arr[] = $item['id'];
                // $arr['name'] = $item['name'];
                if ($item['pid'] != 0) {
                    $arr[] = $this->get_pids($db, $item['pid']);
                    // $arr = array_merge($arr, $this->get_pids($db, $item['pid']));
                }
                $data[] = $arr;
            }
        }
        return $data;
    }
    //递归获取所有的子分类的ID
    function get_ids($array, $id)
    {
        $arr = [];
        foreach ($array as $v) {
            if ($v['pid'] == $id) {
                $arr[] = $v['id'];
                $arr = array_merge($arr, $this->get_ids($array, $v['id']));
            };
        };
        return $arr;
    }



    // 
    // 
    // 
    // 
    // 






    // 按照你的例子，我的记录全等级的方法，查父类0的素有子商品 select * from 商品 left join 分类 on (商品.分类id = 分类.id) where find_in_set(0, 分类.pids)
    // 包不包括自己其实无所谓，不包括你查的时候就要改成select * from 商品 left join 分类 on (商品.分类id = 分类.id) where 分类.id = 0 or find_in_set(0, 分类.pids)
    // 多加个 分类.id = 目标分类 or ，为了方便我都是加上自己的
    // select * from 商品 left join 分类 on (商品.分类id = 分类.id) where find_in_set(0, 分类.pids)
    // 修改 pid ，pids 永远是新的父级的 pids + 自己的id，只不过替换父级，下面自己的所有自己都要递归一遍修改 pids = 父级 pids + 自己的id




    // 新增
    public function new()
    {
        $query = request()->param(); //请求参数
        // $time_int = time();
        // $time = date('Y-m-d H:i:s', $time_int);
        $sqldb = mysql::create(
            [
                'pid' => isset($query['pid']) ? $query['pid'] : 0, //父ID
                'name' =>  isset($query['name']) ? $query['name'] : "未命名分类", //名称
                'i' =>  isset($query['i']) ? $query['i'] : 0, //排序
            ],
            // 许可写入的字段
            [
                'pid', //父ID
                'name', //名称
                'i', //排序
            ]
        );

        // unset($sqldb['sn_pw']); //删除数组中的元素
        $apidb = [
            // 'api' => ["code" => "001", "name" => "用户列表", "help" => $help], //API信息
            'code' => 200, //状态码
            'msg' => '新增成功', //状态信息
            'query' => $query, //请求参数
            // '_header' => request()->header('token'),
            // '_cache' => cache('userdb_' . request()->header('token')),
            // 'data_formerly' => $sqldb, // formerly,now/过去,现在
            'data_now' => $sqldb->toArray(),
            'data' => ['id' => $sqldb->id],


        ];
        // unset($sqldb2); //销毁
        return (json($apidb));
    }
    // 修改
    public function up()
    {
        // $time_int = time();
        // $time = date('Y-m-d H:i:s', $time_int);
        $query = request()->param(); //请求参数
        $sqldb = mysql::where([
            ['id', '=',  $query['id']]
        ])
            ->find();
        // unset($sqldb['sn_pw']); //删除数组中的元素
        $data_formerly = $sqldb->toArray();
        if ($sqldb) {
            $sqldb->name = isset($query['name']) ? $query['name'] : "未命名分类"; //名称
            $sqldb->pid = isset($query['pid']) ? $query['pid'] : 0; //父ID
            $sqldb->i = isset($query['i']) ? $query['i'] : 0; //排序
            $umsg = $sqldb->save();
            if ($umsg  !==   false) {
                $msg = '更新成功!';
                $code = 200;
            } else {
                $msg = '更新失败!';
                $code = 201;
            }
        } else {
            $msg = '查询与更新失败!';
            $code = 202;
        }
        // unset($sqldb['sn_pw']); //删除数组中的元素
        // unset($sqldb['token']); //删除数组中的元素
        // unset($data_formerly['token']); //删除数组中的元素
        $apidb = [
            'code' => $code, //状态码
            'msg' => $msg, //状态信息
            'query' => $query, //请求参数
            'db_old' => $data_formerly,
            'db_now' => $sqldb->toArray(),
        ];
        // unset($sqldb2); //销毁
        return (json($apidb));
    }
    // 删除
    public function del()
    {
    }
    //列表
    public function List()
    {
        $query = request()->param(); //请求参数
        $sqldb = mysql::where([
            ['IdX', '>', -1]
        ])
            ->order("i", "desc")
            ->select()->toArray(); //以数组方式返回
        $cateTree =  $this->get_Tree($sqldb, 0);
        $apidb = [
            'msg' => '导航菜单',
            'code' => 200, //状态码
            // 'sqldb' => $sqldb,
            'Tree' => $cateTree,
            'query' => $query
        ];
        Db::name('ai_t_user_menu_admin_json')
            ->where('user_dbid', '1001')
            ->update([
                'txt_json' => json_encode($cateTree, JSON_UNESCAPED_UNICODE), // 不编码中文
                'txt_json_unicode' => json_encode($cateTree) // 编码中文
            ]);
        // 让我们看一下在使用json_encode()函数时其中一些常用的选项：
        // JSON_FORCE_OBJECT - 强制将编码结果作为对象而不是数组返回
        // JSON_HEX_QUOT - 对双引号进行编码
        // JSON_HEX_TAG - 对HTML标签进行编码
        // JSON_HEX_AMP - 对&符号进行编码
        // JSON_HEX_APOS - 对单引号进行编码
        // JSON_PRETTY_PRINT - 在编码过程中使用缩进和换行符
        // JSON_UNESCAPED_UNICODE - 不进行Unicode编码
        return json($apidb);
    }

    //列表-JSON静态数据
    public function ListJSON()
    {

        $cateTree = Db::name('ai_t_user_menu_admin_json')
            ->where('user_dbid', '1001')
            ->find();

        $txt_json = json_decode($cateTree['txt_json']);
        $txt_json_unicode = json_decode($cateTree['txt_json_unicode']);
        if ($txt_json == null || $txt_json == null) {
            $Tree = [
                'code' => 201, //状态码
                "msg" => '数据JSON处理错误',
            ];
        } else {
            $Tree = [
                "txt_json" => $txt_json,
                "txt_json_unicode" => $txt_json_unicode,
            ];
        }

        $apidb = [
            'msg' => '静态JSON导航菜单树-此接口响应性能更好',
            'code' => 200, //状态码
            'Tree' => $Tree,
        ];
        return json($apidb);
    }
}
